<?php
namespace TennisTournament\Service;

use TennisTournament\Model\GroupStats;
use TennisTournament\Model\Player;
use TennisTournament\Model\WinnerEnum;
use TennisTournament\Persistent\GroupStatsDao;
use Zend\Json\Json;

class GroupStatsServiceImpl implements GroupStatsService {

    /** @var GroupStatsDao */
    protected $groupStatsDao;

    /** @var ResultService */
    protected $resultService;

    public function __construct(GroupStatsDao $groupStatsDao,
            ResultService $resultService) {
        $this->groupStatsDao = $groupStatsDao;
        $this->resultService = $resultService;
    }

    /**
     * Get an {@link GroupStats} entity by its {@link $id}
     * @param $id integer
     * @return GroupStats if have an entity with such id or null otherwise
     * @throws \Exception
     */
    public function get($id) {
        $this->groupStatsDao->startTransaction();
        try {
            /** @var $group GroupStats */
            $groupStat = $this->groupStatsDao->get($id);

            $this->groupStatsDao->commitTransaction();

            return $groupStat;
        } catch(\Exception $ex) {
            $this->groupStatsDao->rollbackTransaction();
            throw $ex;
        }
    }

    /**
     * Get all {@link GroupStats} entities
     * @return Array from all {@link GroupStats}
     * @throws \Exception
     */
    public function fetchAll() {
        $this->groupStatsDao->startTransaction();
        try {
            /** @var $groups array from Group */
            $groupStats = $this->groupStatsDao->fetchAll();

            $this->groupStatsDao->commitTransaction();

            return $groupStats;
        } catch (\Exception $ex) {
            $this->groupStatsDao->rollbackTransaction();
            throw $ex;
        }
    }

    /**
     * Save an specific entity;
     * @param entity
     * @return void
     * @throws \Exception
     */
    public function save($entity) {
        $this->groupStatsDao->startTransaction();
        try {
            $this->groupStatsDao->save($entity);

            $this->groupStatsDao->commitTransaction();
        } catch (\Exception $ex) {
            $this->groupStatsDao->rollbackTransaction();
            throw $ex;
        }
    }

    /**
     * Delete an specific entity;
     * @param entity
     * @return void
     * @throws \Exception
     */
    public function delete($entity) {
        $this->groupStatsDao->startTransaction();
        try {
            $this->groupStatsDao->delete($entity);

            $this->groupStatsDao->commitTransaction();
        } catch (\Exception $ex) {
            $this->groupStatsDao->rollbackTransaction();
            throw $ex;
        }
    }

    /**
     * Encode GroupStats to JSON object
     * @param GroupStats $groupStats
     * @return string
     */
    public function toJSON(GroupStats $groupStats) {
        return Json::encode(
            $groupStats->toArray()
        );
    }


    /**
     * Update player stats depend of results from one Match
     * @param Player $player
     * @param array $collectionResult
     * @param $hostGuest
     * @param $isAWinner
     * @return void
     */
    public function updateStats(Player $player, array $collectionResult, $hostGuest, $isAWinner) {
        $madeScores = 0;
        $obtainedScores = 0;

        /** @var $result Result*/
        foreach($collectionResult as $result) {
            if ($hostGuest == WinnerEnum::HOST) {
                $madeScores += $result->getHostScore();
                $obtainedScores += $result->getGuestScore();
            } else {
                $madeScores += $result->getGuestScore();
                $obtainedScores += $result->getHostScore();
            }
        }

        $player->getGroupStats()->setTakenPoints($player->getGroupStats()->getTakenPoints() + $madeScores);
        $player->getGroupStats()->setGetPoints($player->getGroupStats()->getGetPoints() + $obtainedScores);

        if ($isAWinner) {
            $player->getGroupStats()->setPoints($player->getGroupStats()->getPoints() + 1);
            $player->getGroupStats()->setCountVictories($player->getGroupStats()->getCountVictories() + 1);
        } else {
            $player->getGroupStats()->setCountLosses($player->getGroupStats()->getCountLosses() + 1);
        }

    }
}